<?php
/**
 * Created by PhpStorm.
 * User: edmmss
 * Date: 2020/3/21
 * Time: 9:53 AM
 */

use RongCloud\RongCloud;

class RongCloudApi
{
    // 新的融云域名
    public $serverUrl = 'http://api-cn.ronghub.com/';
    public $spareServerUrl = 'http://api2-cn.ronghub.com/';
    public $ryAppKey; // 填写自己的融云appKey
    public $ryAppSecret; // 填写自己的融云appSecret

    private $_rongCloudApi;
    private $_errorInfo;

    public $statusCodeOk = 200;
    public $platformIos = 'ios';
    public $platformAndroid = 'android';
    public $audienceAll = 'is_to_all';

    /**
     * RongCloudApi constructor.
     */
    public function __construct()
    {
        $rongCloudApi = new RongCloud($this->ryAppKey, $this->ryAppSecret, $this->serverUrl);

        $this->_rongCloudApi = $rongCloudApi;
        $this->_errorInfo = [];
    }

    /**
     * 发送聊天室消息
     *
     * @date   2019/12/12
     * @param int $memberId
     * @param int $chatRoomId
     * @param string $objectName
     * @param $content
     * @return bool|mixed
     * @author edmmss
     */
    public function chatRoomPublish(int $memberId, int $chatRoomId, string $objectName, $content)
    {
        $result = $this->_rongCloudApi->getMessage()->Chatroom()->send([
            'senderId'   => $memberId,
            'targetId'   => $chatRoomId,
            'objectName' => $objectName,
            'content'    => json_encode($content),
        ]);

        $this->setErrorMessage([
            'senderId' => $memberId,
            'targetId' => $chatRoomId,
            'content'  => $content,
        ]);
        $this->setErrorCategory('发送聊天室信息失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 获取聊天室信息
     *
     * @date   2019/12/13
     * @param int $chatRoomId
     * @param int $count
     * @param int $order
     * @return bool|mixed|null
     * @author edmmss
     */
    public function chatRoomQuery(int $chatRoomId, int $count = 1, int $order = 1)
    {
        $result = $this->_rongCloudApi->getChatroom()->get([
            'id'    => $chatRoomId,
            'count' => $count,
            'order' => $order,
        ]);

        $this->setErrorMessage([
            'id'    => $chatRoomId,
            'count' => $count,
            'order' => $order,
        ]);

        if ($result['code'] != $this->statusCodeOk) {
//            Yii::error($result, '获取聊天室信息失败');

            return false;
        } else {
            return $result;
        }
    }

    /**
     * 创建聊天室
     *
     * @date   2019/12/7
     * @param int $chatRoomId
     * @param string $name
     * @return bool|mixed
     * @author edmmss
     */
    public function addChatRoom(int $chatRoomId, string $name)
    {
        $result = $this->_rongCloudApi->getChatroom()->create([
            'id'   => (string)$chatRoomId,
            'name' => $name,
        ]);

        $this->setErrorMessage([
            'id'   => $chatRoomId,
            'name' => $name,
        ]);
        $this->setErrorCategory('聊天室创建失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 群组整体禁言
     *
     * @date   2019-10-23
     * @param int $groupId
     * @return bool|mixed
     * @author edmmss
     */
    public function addBanOverallGroup(int $groupId)
    {
        $result = $this->_rongCloudApi->getGroup()->Gag()->overallAdd([
            'id' => $groupId,
        ]);

        $this->setErrorMessage([
            'groupId' => $groupId,
        ]);
        $this->setErrorCategory('群组整体禁言失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 群组整体移除禁言
     *
     * @date   2019-10-23
     * @param int $groupId
     * @return bool|mixed
     * @author edmmss
     */
    public function rollbackOverallGroup(int $groupId)
    {
        $result = $this->_rongCloudApi->getGroup()->Gag()->rollbackOverallGroup([
            'id' => $groupId,
        ]);

        $this->setErrorMessage([
            'groupId' => $groupId,
        ]);
        $this->setErrorCategory('群组整体移除禁言失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 添加禁言用户白名单
     *
     * @date   2019-10-23
     * @param $members
     * @param int $groupId
     * @return bool|mixed
     * @author edmmss
     */
    public function whitelistAdd($members, int $groupId)
    {
        $result = $this->_rongCloudApi->getGroup()->Gag()->whitelistAdd([
            'members' => $members,
            'id'      => $groupId,
        ]);

        $this->setErrorMessage([
            'memberIds' => $members,
            'groupId'   => $groupId,
        ]);
        $this->setErrorCategory('禁言用户白名单失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 移除禁言用户白名单
     *
     * @date   2019-10-23
     * @param $members
     * @param int $groupId
     * @return bool|mixed
     * @author edmmss
     */
    public function rollbackWhitelist($members, int $groupId)
    {
        $result = $this->_rongCloudApi->getGroup()->Gag()->rollbackWhitelist([
            'members' => $members,
            'id'      => $groupId,
        ]);

        $this->setErrorMessage([
            'memberIds' => $members,
            'groupId'   => $groupId,
        ]);
        $this->setErrorCategory('移除禁言用户白名单失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 发送群组消息
     *
     * @date   2019-08-03
     * @param $objectName
     * @param int $formUserId
     * @param array $toGroupIds
     * @param array $toUserIds
     * @param $contentType
     * @param array $content
     * @param array $contentExtra
     * @return bool|mixed
     * @author edmmss
     */
    public function messageGroupPublish($objectName, int $formUserId, array $toGroupIds, array $toUserIds, $contentType, $content, $contentExtra = [])
    {
        $contentJsonString = json_encode([
            'type'    => (string)$contentType,
            'extra'   => json_encode($contentExtra),
            'content' => $content,
        ]);

        $message = [
            'senderId'   => $formUserId,
            'targetId'   => $toGroupIds,
            'objectName' => $objectName,
            'content'    => $contentJsonString,
        ];

        // 群定向发送
        if ($toUserIds) {
            $message['toUserId'] = $toUserIds;
        }

        return $this->finallyMessageGroupPublish($message);
    }

    /**
     * 最终调用发送群组消息
     *
     * @date   2019-09-27
     * @param $message
     * @return bool|mixed
     * @author edmmss
     */
    public function finallyMessageGroupPublish($message)
    {
        $result = $this->_rongCloudApi->getMessage()->Group()->send($message);

        $this->setErrorMessage($message);
        $this->setErrorCategory('融云发送群组消息失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 发送群@全部人消息
     *
     * @date   2019-09-26
     * @param string $objectName
     * @param int $formUserId
     * @param $toGroupIds
     * @param array $messageContent
     * @return array|bool|mixed
     * @author edmmss
     */
    public function messageGroupMentionAll(string $objectName, int $formUserId, $toGroupIds, array $messageContent)
    {
        $content = json_encode(array_merge($messageContent, [
            'isFull'        => false,
            'mentionedInfo' => [
                'type' => 1,
            ],
        ]));

        $message = [
            'senderId'   => $formUserId,
            'objectName' => $objectName,
            'targetId'   => $toGroupIds,
            'content'    => $content,
        ];

        return $this->finallyMessageGroupMentionAll($message);
    }

    /**
     * 最终调用@群信息
     *
     * @date   2019-09-26
     * @param $message
     * @return bool|mixed
     * @author edmmss
     */
    public function finallyMessageGroupMentionAll($message)
    {
        $result = $this->_rongCloudApi->getMessage()->Group()->sendMention($message);

        $this->setErrorMessage($message);
        $this->setErrorCategory('融云发送群组@消息失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 发送系统消息
     *
     * @date   2019-10-04
     * @param $objectName
     * @param $formUserId
     * @param array $toUserIds
     * @param $contentType
     * @param array $content
     * @param array $contentExtra
     * @param string $pushData
     * @return array|bool|int|mixed
     * @author edmmss
     */
    public function systemPublish($objectName, $formUserId, array $toUserIds, $contentType, array $content, $contentExtra = [], $pushData = '')
    {
        $contentInfo = [
            'type'    => (string)$contentType,
            'extra'   => json_encode($contentExtra),
            'content' => $content,
        ];

        $message = [
            'objectName'       => $objectName,
            'senderId'         => $formUserId,
            'targetId'         => $toUserIds,
            'contentType'      => $contentType,
            'content'          => $contentInfo,
            'extra'            => $contentExtra,
            'pushData'         => $pushData,
            'contentAvailable' => 1,
            'pushContent'      => $content,
        ];

        return $this->finallySystemPublish($message);
    }

    /**
     * 最终调用发送系统消息
     *
     * @date   2019-10-04
     * @param $message
     * @return bool|mixed
     * @author edmmss
     */
    public function finallySystemPublish($message)
    {
        $result = $this->_rongCloudApi->getMessage()->System()->send($message);

        $this->setErrorMessage($message);
        $this->setErrorCategory('融云发送系统消息失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 阿里云MNS调用系统消息
     *
     * @date   2019-07-16
     * @param $formUserId
     * @param $toUserIds
     * @param $objectName
     * @param $content
     * @param $pushContent
     * @return bool|mixed
     * @author edmmss
     */
    public function aliYunMsnSystemPublish($formUserId, $toUserIds, $objectName, $content, $pushData)
    {
        $message = [
            'objectName' => $objectName,
            'senderId'   => $formUserId,
            'targetId'   => $toUserIds,
            'content'    => $content,
            'pushData'   => $pushData,
        ];

        $result = $this->_rongCloudApi->getMessage()->System()->send($message);

        $this->setErrorMessage([
            'objectName' => $objectName,
            'formUserId' => $formUserId,
            'toUserIds'  => $toUserIds,
            'pushData'   => $pushData,
        ]);
        $this->setErrorCategory('融云发送系统消息失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 广播推送信息
     *
     * @date   2019-08-04
     * @param $memberId
     * @param $content
     * @param $alert
     * @param array $platform
     * @return bool|mixed
     * @author edmmss
     */
    public function broadcast($memberId, $content, $alert, $objectName, $platform = [])
    {
        $platform = $platform ? $platform : [$this->platformIos, $this->platformAndroid];

        $message = [
            'senderId'    => $memberId,
            'audience'    => $this->audienceAll,
            'platform'    => $platform,
            'is_to_all'   => true,
            'content'     => $content,
            'alert'       => $alert,
            'objectName'  => $objectName,
            'pushContent' => $content,
        ];

        $result = $this->_rongCloudApi->getMessage()->System()->broadcast($message);

        $this->setErrorMessage([
            'platform' => $platform,
            'content'  => $content,
            'alert'    => $alert,
        ]);
        $this->setErrorCategory('融云广播推送信息');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 移除黑名单中用户
     *
     * @date   2019-08-03
     * @param $memberId
     * @param $beMemberIds
     * @return bool|mixed
     * @author edmmss
     */
    public function blackRemove($memberId, $beMemberIds)
    {
        $result = $this->_rongCloudApi->getUser()->Blacklist()->remove([
            'id'        => $memberId,
            'blacklist' => $beMemberIds,
        ]);

        $this->setErrorMessage([
            'memberId'    => $memberId,
            'beMemberIds' => $beMemberIds,
        ]);
        $this->setErrorCategory('取消用户黑名单失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 添加用户到黑名单
     *
     * @date   2019-06-04
     * @param $memberId
     * @param $beMemberIds
     * @return bool|mixed
     * @author edmmss
     */
    public function blacklistAdd($memberId, $beMemberIds)
    {
        $result = $this->_rongCloudApi->getUser()->Blacklist()->add([
            'id'        => $memberId,
            'blacklist' => $beMemberIds,
        ]);

        $this->setErrorMessage([
            'memberId'    => $memberId,
            'beMemberIds' => $beMemberIds,
        ]);
        $this->setErrorCategory('添加用户黑名单失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 查询用户黑名单列表
     *
     * @date   2019-08-03
     * @param $memberId
     * @return bool|mixed
     * @author edmmss
     */
    public function blacklist($memberId)
    {
        $result = $this->_rongCloudApi->getUser()->Blacklist()->getList([
            'id' => $memberId,
        ]);

        $this->setErrorMessage([
            'memberId' => $memberId,
        ]);
        $this->setErrorCategory('查询用户黑名单失败');

        $result = $this->infoHandle($result, $this->getErrorInfo());

        return $result ? $result['users'] : [];
    }

    /**
     * 检查用户在线状态
     *
     * @date   2019-06-03
     * @param $memberId
     * @return int
     * @author edmmss
     */
    public function checkOnline($memberId)
    {
        $result = $this->_rongCloudApi->getUser()->Onlinestatus()->check([
            'id' => $memberId,
        ]);

        $this->setErrorMessage([
            'memberId' => $memberId,
        ]);
        $this->setErrorCategory('检查用户在线状态失败');

        $result = $this->infoHandle($result, $this->getErrorInfo());

        return $result ? $result['status'] : 0;
    }

    /**
     * 获取token
     *
     * @date   2019-04-25
     * @param $memberId
     * @param $name
     * @param $portraitUri
     * @return bool|mixed
     * @author edmmss
     */
    public function getToken($memberId, $name, $portraitUri)
    {
        $tokenInfo = $this->_rongCloudApi->getUser()->register([
            'id'       => $memberId,
            'name'     => $name,
            'portrait' => $portraitUri,
        ]);

        $this->setErrorMessage([
            'memberId'  => $memberId,
            'tokenInfo' => $tokenInfo,
        ]);
        $this->setErrorCategory('获取融云token失败');

        return $this->infoHandle($tokenInfo, $this->getErrorInfo());
    }

    /**
     * 创建群组
     *
     * @date   2019-04-25
     * @param $memberIds
     * @param $groupId
     * @param $groupName
     * @return bool|mixed
     * @author edmmss
     */
    public function groupCreate($memberIds, $groupId, $groupName)
    {
        $members = [];
        foreach ($memberIds as $memberId) {
            $members[]['id'] = $memberId;
        }

        $result = $this->_rongCloudApi->getGroup()->create([
            'id'      => $groupId,
            'name'    => $groupName,
            'members' => $members,
        ]);

        $this->setErrorMessage([
            'memberId'  => $memberIds,
            'groupId'   => $groupId,
            'groupName' => $groupName,
        ]);
        $this->setErrorCategory('创建融云群组失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 加入群组
     *
     * @date   2019-04-25
     * @param $memberId
     * @param $groupId
     * @param $groupName
     * @return bool|mixed
     * @author edmmss
     */
    public function joinGroup($memberId, $groupId, $groupName)
    {
        $result = $this->_rongCloudApi->getGroup()->joins([
            'id'     => $groupId,
            'name'   => $groupName,
            'member' => [
                'id' => $memberId,
            ],
        ]);

        $this->setErrorMessage([
            'memberId'  => $memberId,
            'groupId'   => $groupId,
            'groupName' => $groupName,
        ]);
        $this->setErrorCategory('加入融云群组失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 查询群成员
     *
     * @date   2019-08-03
     * @param $groupId
     * @return array
     * @author edmmss
     */
    public function userQuery($groupId)
    {
        $result = $this->_rongCloudApi->getGroup()->get([
            'id' => $groupId,
        ]);

        $this->setErrorMessage([
            'groupId' => $groupId,
        ]);
        $this->setErrorCategory('查询融云群成员失败');

        $result = $this->infoHandle($result, $this->getErrorInfo());

        return $result ? $result['members'] : [];
    }

    /**
     * 退出群组
     *
     * @date   2019-04-25
     * @param $memberId
     * @param $groupId
     * @return bool|mixed
     * @author edmmss
     */
    public function quitGroup($memberId, $groupId)
    {
        $result = $this->_rongCloudApi->getGroup()->quit([
            'id'     => $groupId,
            'member' => [
                'id' => $memberId,
            ],
        ]);

        $this->setErrorMessage([
            'memberId' => $memberId,
            'groupId'  => $groupId,
        ]);
        $this->setErrorCategory('融云退出群组失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 解散群组
     *
     * @date   2019-05-08
     * @param $memberId
     * @param $groupId
     * @return bool|mixed
     * @author edmmss
     */
    public function dismissGroup($memberId, $groupId)
    {
        $result = $this->_rongCloudApi->getGroup()->dismiss([
            'id'     => $groupId,
            'member' => [
                'id' => $memberId,
            ],
        ]);

        $this->setErrorMessage([
            'memberId' => $memberId,
            'groupId'  => $groupId,
        ]);
        $this->setErrorCategory('融云解散群组失败');

        return $this->infoHandle($result, $this->getErrorInfo());
    }

    /**
     * 设置sentry错误信息
     *
     * @date   2019-04-25
     * @param $errorMessage
     * @author edmmss
     */
    private function setErrorMessage($errorMessage)
    {
        $this->_errorInfo['message'] = $errorMessage;
    }

    /**
     * 设置sentry错误类别
     *
     * @date   2019-04-25
     * @param $category
     * @author edmmss
     */
    private function setErrorCategory($category)
    {
        $this->_errorInfo['category'] = $category;
    }

    /**
     * 获取错误信息数组
     *
     * @date   2019-04-25
     * @return array
     * @author edmmss
     */
    private function getErrorInfo()
    {
        return $this->_errorInfo;
    }

    /**
     * 信息统一处理
     *
     * @date   2019-04-25
     * @param $info
     * @param $errorInfo
     * @return bool|mixed
     * @author edmmss
     */
    private function infoHandle($info, $errorInfo)
    {
        if ($info['code'] != $this->statusCodeOk) {
            Yii::error(array_merge($errorInfo['message'], [
                'errorInfo' => $info['msg'],
            ]), $errorInfo['category']);

            return false;
        } else {
            return $info;
        }
    }
}